% Author: Andrew Fox
% Estimates response times of a VM based on server resources
function [theta,P,K,R]=estimator(lambda,numinputs,R,phi,theta,P,y)
tol=5E-2;
thetaOld=theta;
PPP=phi'*P*phi;


if (PPP>0*(1-lambda))
    M=(1-lambda)*(R*(phi*phi'))*(phi'*R*phi)^-1;
    Ptild=P+(1-lambda)/lambda*(phi*phi')/(phi'*R*phi);
else
    M=zeros(numinputs,numinputs);
    Ptild=P;
end
R=(eye(numinputs)-M)*R+phi*phi';
K=(Ptild*phi)*(1+phi'*Ptild*phi)^-1;
theta=theta+K*(y-phi'*theta);

iter=0;
passive=false(numinputs,1);
active=true(numinputs,1);

while(iter<5&&any(theta<tol))
    iter=iter+1;
    iter2=0;
    passive(theta>tol)=true;
    active=~passive;
    s=zeros(numinputs,1);
    s(passive)=thetaOld(passive)+K(passive)*(y-phi(passive)'*thetaOld(passive));
    while(any(s(passive)<tol)&&iter2<5)
        iter2=iter2+1;
        Q=(s <= tol)&passive;
        alpha=-min(theta(Q)./(theta(Q)-s(Q)));
        theta=theta+alpha*(s-theta);
        %DOES THIS NEXT LINE MAKE SENSE?
        %                 active=(theta<=tol);
        %                  passive = ~active;
        passive(theta>tol)=true;
        active=~passive;
        s(passive)=thetaOld(passive)+K(passive)*(y-phi(passive)'*thetaOld(passive));
    end
    theta(passive)=s(passive);
    theta(active)=0;
end

P=Ptild-(Ptild*phi*phi'*Ptild)*(1+phi'*Ptild*phi)^(-1);

end